import 'dart:async';
import 'dart:convert';

import 'package:exread/ScanQRCode.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

class Books extends StatefulWidget {
  @override
  createState() => new BooksState();
}

class BooksState extends State<Books> {
  var _books = <Book>[];
  Book _pressBook;


  @override
  void initState() {
    _loadData();
  }

  //http 加载数据
  Future<Null> _loadData() async {
    print("load book data");
    String dataUrl = "https://api.bmob.cn/1/classes/book/";

    //设置请求头
    Map<String, String> map = new Map();
    map["X-Bmob-Application-Id"] = "ce30565639d0fb10cd925b5b024c3408";
    map["X-Bmob-REST-API-Key"] = "4057ff07b1bec5590fb4ff0a16141938";
    try {
      http.Response response = await http.get(dataUrl, headers: map);
      print("${response.body}");

      BookResponse baseResponse = new BookResponse(response.body);
      setState(() {
        _books = baseResponse.data;
      });
    } on Exception catch (e) {
      print("exception $e");
      SnackBar mSnackBar = new SnackBar(content: new Text("加载数据错误"));
      Scaffold.of(context).showSnackBar(mSnackBar);
    }
    return null;
  }

  void addBook() {
    Book book = new Book(
        "111", "https://img3.doubanio.com/mpic/s1914861.jpg", "时间简史", "中国文学出版社",
        "霍金");
    _postData(book);
  }

  //添加一本新书
  void _postData(Book book) async {
    String dataUrl = "https://api.bmob.cn/1/classes/book/";

    //设置请求头
    Map<String, String> map = new Map();
    map["Content-Type"] = "application/json";
    map["X-Bmob-Application-Id"] = "ce30565639d0fb10cd925b5b024c3408";
    map["X-Bmob-REST-API-Key"] = "4057ff07b1bec5590fb4ff0a16141938";
    try {
      http.Response response = await http.post(
          dataUrl, headers: map, body: json.encode(book));
      print("${response.body}");
    } on Exception catch (e) {
      print("exception $e");
      SnackBar mSnackBar = new SnackBar(content: new Text("上传数据错误"));
      Scaffold.of(context).showSnackBar(mSnackBar);
    }
  }

  //添加一本新书
  void _deleteData(Book book) async {
    String dataUrl = "https://api.bmob.cn/1/classes/book/" + book.id;

    //设置请求头
    Map<String, String> map = new Map();
    map["Content-Type"] = "application/json";
    map["X-Bmob-Application-Id"] = "ce30565639d0fb10cd925b5b024c3408";
    map["X-Bmob-REST-API-Key"] = "4057ff07b1bec5590fb4ff0a16141938";
    try {
      http.Response response = await http.delete(
          dataUrl, headers: map);
      print("${response.body}");
      setState(() {
        bool re = _books.remove(book);
        print("remove book when delete $re.");
      });
    } on Exception catch (e) {
      print("exception $e");
      SnackBar mSnackBar = new SnackBar(content: new Text("删除数据错误"));
      Scaffold.of(context).showSnackBar(mSnackBar);
    }
  }


  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        backgroundColor: Colors.lightBlue,
        body: new Container(
            decoration: new BoxDecoration(
                gradient: new LinearGradient(
                  begin: FractionalOffset.topCenter,
                  end: FractionalOffset.bottomCenter,
                  colors: [
                    const Color.fromARGB(255, 106, 200, 243),
                    const Color.fromARGB(255, 52, 130, 191),
                  ],
                  stops: [0.0, 1.0],
                )
            ),
            child: new RefreshIndicator(
                onRefresh: () => _loadData(),
                child: ListView.builder(
                    physics: const AlwaysScrollableScrollPhysics(),
                    itemCount: _books.length,
                    itemBuilder: (context, i) {
                      print("books size ${_books
                          .length} item builder position $i ${_books[i]}");
                      return _buildRow(_books[i]);
                    }
                ))
        ),
        floatingActionButton: new FloatingActionButton(
          onPressed: () async {

            //页面跳转并处理返回值
            String result = await Navigator.push(context, new MaterialPageRoute(builder: (context) => new ScanQRCode()));
            print ("result $result");
            if (result != null && result.isNotEmpty) {//有返回值，有新书添加，则刷新数据
              _loadData();
            }
          },
          tooltip: '发布新书',
          child: new Icon(Icons.add),
        )
    );
  }

  //构造数据Item视图
  Widget _buildRow(Book book) {
    final TextStyle nameStyle = new TextStyle(
        fontSize: 18.0, color: Colors.black54);
    final TextStyle authorStyle = new TextStyle(
        fontSize: 15.0, color: Colors.blueGrey);
    final TextStyle publisherStyle = new TextStyle(
        fontSize: 12.0, color: Colors.blueGrey);

    RelativeRect pressRect;
    double opacity = 0.2;
    if (_pressBook != null && book.bookName == _pressBook.bookName) {
      opacity = 0.5;
    }
    print("_buildRow name ${book.bookName}");

    return new GestureDetector(
      child: new Container(
        margin: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 5.0),
        padding: const EdgeInsets.symmetric(horizontal: 15.0, vertical: 10.0),
        decoration: new BoxDecoration(
          color: Colors.grey.shade200.withOpacity(opacity),
          borderRadius: new BorderRadius.circular(5.0),
        ),
        child: new Row(
          children: <Widget>[
            new Image.network(book.coverImage, width: 80.0, height: 100.0,),
            new Container(
              padding: new EdgeInsets.symmetric(horizontal: 15.0),
              child: new Column (
                crossAxisAlignment: CrossAxisAlignment.start,
                children: <Widget>[
                  new Text(
                      book.bookName, style: nameStyle,
                      textAlign: TextAlign.left),
                  new Text(book.author, style: authorStyle),
                  new Text(book.publisher, style: publisherStyle),
                ],
              ),)
          ],

        ),

      ), onTap: () { //单击
      SnackBar bar = new SnackBar(content: new Text(book.bookName));
      Scaffold.of(context).showSnackBar(bar);
    },
      onLongPress: () async { //长按
        setState(() {
          _pressBook = book;
        });

        //弹出删除菜单，showMenu使用的是future模式，会在此处阻塞
        //菜单消失时，会返回选中的项，否则为null
        String select = await showMenu<String>(items: <PopupMenuEntry<String>>[
          new PopupMenuItem(value: "delete", child: new Text("删除"))],
            context: context
            ,
            position: pressRect);
        print("show menu selected $select");
        if (select == "delete") {
          _deleteData(book);
        }
        setState(() {
          _pressBook = null;
        });
      },
      onTapDown: (tapDetail) { //记录点击的位置
        pressRect = new RelativeRect.fromLTRB(
            tapDetail.globalPosition.dx, tapDetail.globalPosition.dy, 0.0, 0.0);
      },

    );
  }
}


//解析返回的数据
class BookResponse {
  var total;
  var response;
  var data = <Book>[];

  BookResponse(String jsonStr) {
    Map map = JSON.decode(jsonStr);
    response = map["results"];
    print("total ${(response as List).length}");
    (response as List).forEach((B) => data.add(new Book.fromJson(B)));
  }
}

//数据实体类
class Book {
  String id;
  String isbn;
  String coverImage;
  String bookName;
  String publisher;
  String author;

  Book(this.isbn, this.coverImage, this.bookName, this.publisher, this.author);

  Book.fromJson(Map<String, dynamic> json)
      :isbn = json["isbn"],
        coverImage = json["coverImage"],
        bookName = json["bookName"],
        publisher = json["publisher"],
        author = json["author"],
        id = json["objectId"];

  Book.fromDuoban(Map<String, dynamic> json)
      :isbn = json["isbn13"],
        coverImage = json["images"]["medium"],
        bookName = json["title"],
        publisher = json["publisher"],
        author = json["author"][0];


  Map<String, dynamic> toJson() =>
      {
        'isbn': isbn,
        'coverImage': coverImage,
        'bookName': bookName,
        'publisher': publisher,
        'author': author,
      };
}